#ifndef THREADPOOL_H
#define THREADPOOL_H

#include <vector>
#include <queue>
#include <functional>
#include <condition_variable>
#include <mutex>
#include <thread>
#include <atomic>
#include<unordered_map>
#include<iostream>

const int TASK_MAX_THRESHHOLD = INT32_MAX;
const int THREAD_MAX_THRESHHOLD = 10;
const int THREAD_MAX_IDLE_TIME = 60;
enum PoolMode
{
    MODE_FIXED,  // 固定数量线程
    MODE_CACHED, // 线程数量动态增长

};

class Thread
{
public:
    // 线程函数对象类型
    using ThreadFunc = std::function<void(int)>;
    // 构造
    Thread(ThreadFunc func);
    // 析构函数
    ~Thread();

    Thread(const Thread&) = delete;
    Thread& operator=(const Thread&) = delete;
    // 启动线程
    void start();

    int getId()const;
private:
    ThreadFunc func_;
    int threadId_;//保存线程id
    static int generateId_;
};


class ThreadPool
{
public:
    ThreadPool();
    ~ThreadPool();

    void setMode(PoolMode mode);

    void setTaskMaxSize(int size);


    //设置chched模式下线程的最大值
    void setThreadSizeMAx(int size);


    void start(int initThreadSize = 4); // 开启线程池

    // 给线程池提交任务
    template <class T>
    void submitTask(T&& task)
    {
        std::unique_lock<std::mutex> lock(taskQueMtx_);
        // while(taskQueMtx_.size()==taskSizeThreshHold_)
        // {
        //     notFull_.wait(lock);
        // }
        // 如果是满的，释放锁
        // 如果不满，持有锁
        if (!notFull_.wait_for(lock, std::chrono::seconds(1), [&]() -> bool
            { return tasks_.size() < taskSizeThreshHold_; }))
        {
            // 表示noytFull_等待1s条件依然没有满足
            std::cerr << "任务提交超时";
            return;
        }

        tasks_.emplace(task);
        taskSize_++;
        //
        notEmpty_.notify_one(); // 放了任务不空

        //cached模式
        if (poolmode_ == PoolMode::MODE_CACHED && taskSize_ > idleThreadSize_
            && curThreadSumSize_ < threadMaxSize)
        {
            std::cout << "create new thread " << std::endl;
            //创建新线程
            auto ptr = std::make_unique<Thread>(std::bind(&ThreadPool::threadFunc, this, std::placeholders::_1));
            //threads_.emplace_back(std::move(ptr));
            int threadId = ptr->getId();
            threads_.emplace(threadId, std::move(ptr));
            threads_[threadId]->start();//启动线程
            curThreadSumSize_++;    
            idleThreadSize_++;
        }
        return;
    }

    // 定义线程函数
    void threadFunc(int threadid);
    

private:

    //检查pool的运行状态
    bool checkRunningState()const;

private:
    //std::vector<std::unique_ptr<Thread>> threads_; // 线程列表
    std::unordered_map<int, std::unique_ptr<Thread>>threads_;//线程列表

    int initThreadSize_;                           // 初始线程数量

    std::queue<std::function<void()>> tasks_; // 任务队列
    std::atomic_int taskSize_;                // 任务数量
    int taskSizeThreshHold_;                  // 任务队列阈值

    std::mutex taskQueMtx_;            // 保证任务队列的线程安全
    std::condition_variable notFull_;  // 任务队列不满
    std::condition_variable notEmpty_; // 任务队列不空

    PoolMode poolmode_;

    std::atomic_bool isPoolRunning_;

    //记录空闲线程的数量
    std::atomic_int idleThreadSize_;

    //线程数量上的阈值
    int threadMaxSize;

    //记录线程池里线程的总数量
    std::atomic_int curThreadSumSize_;

    std::condition_variable exitCond_;//等待线程资源全部回收
};

#endif